<template>
  <div>
    <div class="demo-upload-list" v-for="(item, index) in uploadList" :key="'upload_' + index">
      <template v-if="item.status === 'finished'">
        <img v-if="item.url" :src="item.url | checkImgPrefix" />
        <img v-else :src="item.response.data[0] | checkImgPrefix" />
        <div class="demo-upload-list-cover">
          <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
          <Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
        </div>
      </template>
      <template v-else>
        <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
      </template>
    </div>
    <Upload
      v-show="(multiple && uploadList.length < maxLength) || (uploadList.length < 1)"
      ref="upload"
      :show-upload-list="showUploadList"
      :default-file-list="defaultFilelist"
      :on-success="handleSuccess"
      :on-error="onError"
      :on-preview="onPreview"
      :format="format"
      :max-size="maxSize"
      :on-format-error="handleFormatError"
      :before-upload="handleBeforeUpload"
      :multiple="multiple"
      :action="fileUploadUrl"
      :name="name"
      type="drag"
      style="display: inline-block;width:58px;"
      :on-exceeded-size="handleMaxSize"
    >
      <div style="width: 58px;height:58px;line-height: 58px;">
        <Icon type="ios-camera" size="20"></Icon>
      </div>
    </Upload>
    <Modal draggable title="图片预览" :z-index="10000" v-model="visible">
      <img :src="imgName | checkImgPrefix" v-if="visible" style="width: 100%" />
    </Modal>
  </div>
</template>

<script>
export default {
  name: 'file-upload',
  props: {
    maxLength: {
      type: Number,
      default() {
        return 10
      }
    },
    // imgName: {
    //   type: String,
    //   default() {
    //     return '';
    //   }
    // },
    // 上传的地址，必填
    action: {
      type: String,
      default() {
        return ''
      }
    },
    // 设置上传的请求头部
    headers: {
      type: Object,
      default() {
        return {}
      }
    },
    // 是否支持多选文件
    multiple: {
      type: Boolean,
      default() {
        return false
      }
    },
    // 是否支持粘贴上传文件
    paste: {
      type: Boolean,
      default() {
        return false
      }
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default() {
        return false
      }
    },
    // 上传时附带的额外参数
    data: {
      type: Object,
      default() {
        return {}
      }
    },
    // 上传的文件字段名
    name: {
      type: String,
      default() {
        return 'images'
      }
    },
    // 支持发送 cookie 凭证信息
    withCredentials: {
      type: Boolean,
      default() {
        return false
      }
    },
    // 是否显示已上传文件列表
    showUploadList: {
      type: Boolean,
      default() {
        return false
      }
    },
    // 上传控件的类型，可选值为 select（点击选择），drag（支持拖拽）
    type: {
      type: String,
      default() {
        return 'select'
      }
    },
    // 接受上传的文件类型
    accept: {
      type: String,
      default() {
        return ''
      }
    },
    // 支持的文件类型，与 accept 不同的是，format 是识别文件的后缀名，accept 为 input 标签原生的 accept 属性，会在选择文件时过滤，可以两者结合使用
    format: {
      type: Array,
      default() {
        return ['jpg', 'jpeg', 'png']
      }
    },
    // 文件大小限制，单位 kb
    maxSize: {
      type: Number,
      default: 1024
    },
    // 上传文件之前的钩子，参数为上传的文件，若返回 false 或者 Promise 则停止上传
    beforeUpload: {
      type: Function
    },
    // 文件上传时的钩子，返回字段为 event, file, fileList
    onProgress: {
      type: Function
    },
    onError: {
      type: Function
    },
    onPreview: {
      type: Function
    },
    onRemove: {
      type: Function
    },
    onFormatError: {
      type: Function
    },
    onExceededSize: {
      type: Function
    },
    defaultFilelist: {
      type: Array,
      default() {
        return []
        //   [

        //   // {
        //   //     'name': 'a42bdcc1178e62b4694c830f028db5c0',
        //   //     'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'
        //   // },
        //   // {
        //   //     'name': 'bc7521e033abdd1e92222d733590f104',
        //   //     'url': 'https://o5wwk8baw.qnssl.com/bc7521e033abdd1e92222d733590f104/avatar'
        //   // }
        // ],
      }
    }
  },
  data() {
    return {
      visible: false,
      uploadList: [],
      imgName: '',
      userImgUrl: '1'
    }
  },
  computed: {
    fileUploadUrl() {
      if (this.action) {
        return this.$config.baseUrl.BASE_URL + this.action
      } else {
        return this.$config.baseUrl.FILE_UPLOAD_URL
      }
    }
  },

  methods: {
    handleView(item) {
      if (item.url) {
        // this.imgName = this.$options.filters.checkImgPrefix(item.url);
        this.imgName = item.url
      } else {
        this.imgName = item.response.data[0]
      }
      this.visible = true
    },
    handleRemove(file) {
      console.log('handleRemove')
      this.userImgUrl = ''
      this.$emit('setUserImgUrl', this.userImgUrl)
      const fileList = this.$refs.upload.fileList
      this.$refs.upload.fileList.splice(fileList.indexOf(file), 1)
    },
    handleSuccess(res, file) {
      // M00/01/32/rBBm41262XOAHXNNAAAA_EDRjT4683.png
      // console.log(res, file, this.$refs.upload.fileList);
      // this.imgName = res.data[0];
      // debugger;
      this.uploadList = this.$refs.upload.fileList
      console.log(this.uploadList)
      this.$emit('on-success', res, this.$refs.upload.fileList)
      // this.$emit()
    },
    handleFormatError(file) {
      this.$Notice.warning({
        title: '文件格式错误',
        desc: file.name + '文件格式错误, 请上传 jpg or png'
      })
    },
    handleMaxSize(file) {
      this.$Notice.warning({
        title: '文件大小限制',
        desc: file.name + '文件太大了，请上传小于' + (this.maxSize / 1024) + 'M的文件'
      })
    },
    handleBeforeUpload(file) {
      const check = this.uploadList.length < this.maxLength
      if (!check) {
        this.$Notice.warning({
          title: '最多可以上传' + this.maxLength + '个文件'
        })
      } else {
        console.log(file)
      }
      return check
    },
    convertBase64ToBlob(base64) {
      let base64Arr = base64.split(',')
      let imgtype = ''
      let base64String = ''
      if (base64Arr.length > 1) {
        // 如果是图片base64，去掉头信息
        base64String = base64Arr[1]
        imgtype = base64Arr[0].substring(base64Arr[0].indexOf(':') + 1, base64Arr[0].indexOf(';'))
      }
      // 将base64解码
      let bytes = atob(base64String)
      // var bytes = base64;
      let bytesCode = new ArrayBuffer(bytes.length)
      // 转换为类型化数组
      let byteArray = new Uint8Array(bytesCode)

      // 将base64转换为ascii码
      for (let i = 0; i < bytes.length; i++) {
        byteArray[i] = bytes.charCodeAt(i)
      }

      // 生成Blob对象（文件对象）
      return new Blob([bytesCode], { type: imgtype })
    },
    compressImage(file, success, error) {
      const name = file.name // 文件名
      let imgtype = name.substring(name.lastIndexOf('.') + 1).toLowerCase()
      if (imgtype === 'jpg' || imgtype === 'jpeg') {
        imgtype = 'image/jpeg'
      } else {
        imgtype = 'image/png'
      }
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = e => {
        const src = e.target.result

        const img = new Image()
        img.src = src
        img.onload = e => {
          const quality = (1024 * 1024) / file.size // 默认图片质量为0.92
          const w = quality >= 1 ? img.width : img.width * quality
          const h = quality >= 1 ? img.height : img.height * quality
          // 生成canvas
          const canvas = document.createElement('canvas')
          canvas.setAttribute('width', w)
          canvas.setAttribute('height', h)
          const ctx = canvas.getContext('2d')

          // 铺底色 PNG转JPEG时透明区域会变黑色
          // ctx.fillStyle = "#fff";
          // ctx.fillRect(0, 0, w, h);

          ctx.drawImage(img, 0, 0, w, h)
          // quality值越小，所绘制出的图像越模糊
          let base64 = canvas.toDataURL(imgtype, 0.9) // 图片格式jpeg或webp可以选0-1质量区间

          success(this.convertBase64ToBlob(base64), {
            name: name,
            type: 'image/jpeg',
            size: file.length
          })
        }
        img.onerror = e => {
          error(e)
        }
      }
      reader.onerror = e => {
        error(e)
      }
    }
  },
  mounted() {
    this.uploadList = this.$refs.upload.fileList
  },
  watch: {
    defaultFilelist() {
      // console.log('defaultChange', this.$refs.upload.fileList);
      setTimeout(() => {
        this.uploadList = this.$refs.upload.fileList
      })
    }
  }
}
</script>
<style>
.demo-upload-list {
  display: inline-block;
  width: 60px;
  height: 60px;
  text-align: center;
  line-height: 60px;
  border: 1px solid transparent;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
  position: relative;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  margin-right: 4px;
}
.demo-upload-list img {
  width: 100%;
  height: 100%;
}
.demo-upload-list-cover {
  display: none;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.6);
}
.demo-upload-list:hover .demo-upload-list-cover {
  display: block;
}
.demo-upload-list-cover i {
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  margin: 0 2px;
}
</style>
